package jwcb.javapjframework.ms_template.service.service;

import com.fasterxml.jackson.core.type.TypeReference;
import jwcb.javapjframework.common.redis.RedisService.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Set;

@Service
public class RedisZSetTestService {

    @Autowired
    private RedisService redisService;

    private static final String TEST_KEY = "test:zset:operations";

    public String testRedisZSetOperations() {
        StringBuilder result = new StringBuilder();
        result.append("Redis ZSet 操作测试开始...\n\n");

        try {
            // 清理旧数据
            redisService.deleteObject(TEST_KEY);
            
            // 1. 添加元素测试
            redisService.addZSetMember(TEST_KEY, "A", 10);
            redisService.addZSetMember(TEST_KEY, "B", 20);
            redisService.addZSetMember(TEST_KEY, "C", 30);
            redisService.addZSetMember(TEST_KEY, "D", 40);
            redisService.addZSetMember(TEST_KEY, "E", 50);
            
            Long initialSize = redisService.getZSetSize(TEST_KEY);
            result.append("测试1: 添加元素\n")
                  .append("预期大小: 5, 实际大小: ").append(initialSize).append("\n")
                  .append("结果: ").append(initialSize == 5 ? "成功" : "失败").append("\n\n");

            // 2. 按分数范围获取元素(正序，不带分页)
            Set<String> scoreRange = redisService.getZSetByScoreRange(TEST_KEY, 15, 35, new TypeReference<Set<String>>() {});
            result.append("测试2: 按分数范围获取(正序)[15-35]\n")
                  .append("预期: [B, C], 实际: ").append(scoreRange).append("\n")
                  .append("结果: ").append(scoreRange.equals(Set.of("B", "C")) ? "成功" : "失败").append("\n\n");

            // 3. 按分数范围获取元素(正序，带分页)
            Set<String> scoreRangePaged = redisService.getZSetByScoreRange(TEST_KEY, 10, 50, 1, 2, new TypeReference<Set<String>>() {});
            result.append("测试3: 按分数范围获取(正序分页)[10-50], offset=1, count=2\n")
                  .append("预期: [B, C], 实际: ").append(scoreRangePaged).append("\n")
                  .append("结果: ").append(scoreRangePaged.equals(Set.of("B", "C")) ? "成功" : "失败").append("\n\n");

            // 4. 按分数范围获取元素(倒序，不带分页)
            Set<String> scoreRangeDesc = redisService.getZSetByScoreRangeDesc(TEST_KEY, 15, 35, new TypeReference<Set<String>>() {});
            result.append("测试4: 按分数范围获取(倒序)[15-35]\n")
                  .append("预期: [C, B], 实际: ").append(scoreRangeDesc).append("\n")
                  .append("结果: ").append(scoreRangeDesc.equals(Set.of("C", "B")) ? "成功" : "失败").append("\n\n");

            // 5. 按分数范围获取元素(倒序，带分页)
            Set<String> scoreRangeDescPaged = redisService.getZSetByScoreRangeDesc(TEST_KEY, 10, 50, 1, 2, new TypeReference<Set<String>>() {});
            result.append("测试5: 按分数范围获取(倒序分页)[10-50], offset=1, count=2\n")
                  .append("预期: [D, C], 实际: ").append(scoreRangeDescPaged).append("\n")
                  .append("结果: ").append(scoreRangeDescPaged.equals(Set.of("D", "C")) ? "成功" : "失败").append("\n\n");

            // 6. 按索引范围获取元素(正序)
            Set<String> indexRange = redisService.getZSetByIndexRange(TEST_KEY, 1, 3, new TypeReference<Set<String>>() {});
            result.append("测试6: 按索引范围获取(正序)[1-3]\n")
                  .append("预期: [B, C, D], 实际: ").append(indexRange).append("\n")
                  .append("结果: ").append(indexRange.equals(Set.of("B", "C", "D")) ? "成功" : "失败").append("\n\n");

            // 7. 按索引范围获取元素(倒序)
            Set<String> indexRangeDesc = redisService.getZSetByIndexRangeDesc(TEST_KEY, 0, 1, new TypeReference<Set<String>>() {});
            result.append("测试7: 按索引范围获取(倒序)[0-1]\n")
                  .append("预期: [E, D], 实际: ").append(indexRangeDesc).append("\n")
                  .append("结果: ").append(indexRangeDesc.equals(Set.of("E", "D")) ? "成功" : "失败").append("\n\n");

            // 8. 获取元素分数
            Double scoreB = redisService.getZSetScore(TEST_KEY, "B");
            result.append("测试8: 获取元素分数(B)\n")
                  .append("预期: 20.0, 实际: ").append(scoreB).append("\n")
                  .append("结果: ").append(scoreB != null && scoreB == 20.0 ? "成功" : "失败").append("\n\n");

            // 9. 统计分数范围内元素数量
            Long countInRange = redisService.countZSetByScore(TEST_KEY, 25, 45);
            result.append("测试9: 统计分数范围元素数量[25-45]\n")
                  .append("预期: 2, 实际: ").append(countInRange).append("\n")
                  .append("结果: ").append(countInRange == 2 ? "成功" : "失败").append("\n\n");

            // 10. 获取有序集合大小
            Long size = redisService.getZSetSize(TEST_KEY);
            result.append("测试10: 获取有序集合大小\n")
                  .append("预期: 5, 实际: ").append(size).append("\n")
                  .append("结果: ").append(size == 5 ? "成功" : "失败").append("\n\n");

            // 11. 增加元素分数
            Double newScore = redisService.incrementZSetScore(TEST_KEY, "A", 15);
            result.append("测试11: 增加元素分数(A增加15)\n")
                  .append("预期新分数: 25.0, 实际: ").append(newScore).append("\n")
                  .append("结果: ").append(newScore == 25.0 ? "成功" : "失败").append("\n\n");

            // 12. 获取元素排名(正序)
            Long rankC = redisService.getZSetRank(TEST_KEY, "C");
            result.append("测试12: 获取元素排名(正序)C\n")
                  .append("预期排名: 2(从0开始), 实际: ").append(rankC).append("\n")
                  .append("结果: ").append(rankC == 2 ? "成功" : "失败").append("\n\n");

            // 13. 获取元素排名(倒序)
            Long reverseRankC = redisService.getZSetReverseRank(TEST_KEY, "C");
            result.append("测试13: 获取元素排名(倒序)C\n")
                  .append("预期排名: 2(从0开始), 实际: ").append(reverseRankC).append("\n")
                  .append("结果: ").append(reverseRankC == 2 ? "成功" : "失败").append("\n\n");

            // 14. 根据排名范围删除元素
            Long removedCount = redisService.removeZSetRangeByRank(TEST_KEY, 0, 1);
            Set<String> afterRemove = redisService.getCacheZSet(TEST_KEY, new TypeReference<Set<String>>() {});
            result.append("测试14: 根据排名范围删除[0-1]\n")
                  .append("预期删除数量: 2, 实际: ").append(removedCount).append("\n")
                  .append("剩余元素: ").append(afterRemove).append("\n")
                  .append("结果: ").append(removedCount == 2 && afterRemove.equals(Set.of("C", "D", "E")) ? "成功" : "失败").append("\n\n");

            result.append("✅ 所有ZSet操作测试完成!");

        } catch (Exception e) {
            result.append("\n❌ 测试异常: ").append(e.getMessage());
            e.printStackTrace();
        } finally {
            // 清理测试数据
            redisService.deleteObject(TEST_KEY);
        }

        return result.toString();
    }
}